Combining Plots Produced by Diana with Python

This document aims to show how to produce plots using Diana and combine them to create new products.

Installation

To get access to the Python modules that expose Diana's plotting features, you need to install the python-diana package from the local package repository. Either use the package manager to do this, or enter the following in a terminal:

apt-get install python-diana

Some examples can also be found in the python-diana-examples package.

Importing Modules

You can use Diana's functionality from Python by importing the bdiana and plotcommands modules from the metno package. If you are using an old version of ipython (earlier than version 1.0) then it is also useful to import the embed function from the metno.ipython_extensions module. The pyproj module is used to describe projections in a way that Diana understands. We also import the datetime module so that we can pass a time to Diana without needing to obtain one from a data file.


In [1]:
# Import the modules needed to use Diana.
from metno import bdiana, plotcommands
# Import an extension that lets us embed an image into a worksheet.
from metno.ipython_extensions import embed

Initialisation and Setup

The bdiana module contains the BDiana class. This provides a convenient interface to Diana's functions and also wraps several initialisation steps into one object. To start using Diana, we simply create an instance of this class and load a setup file that describes where various resources are located and set it up using a setup file located on the user's system.


In [2]:
b = bdiana.BDiana()
b.setup("/etc/diana/setup/diana.setup-COMMON")

Creating a Picture

We create a new plot in the usual way, creating plot commands to describe the area, map and field, then plotting the data for the last available time.


In [3]:
a = plotcommands.Area(name="Norge")
m = plotcommands.Map(map="Gshhs-Auto", backcolour="white", land="on")
m.setOption("land.colour", "flesh")

f = plotcommands.Field(model="HIRLAM.12KM.00", plot="air_temperature_2m",
                       plottype="contour", palettecolours="standard",
                       linetype="solid", linewidth=1, unit="celsius")
f.setOption("line.interval", 2)
times = b.getFieldTimes(f.options["model"], f.options["plot"])
b.setPlotCommands([a.text(), m.text(), f.text()])
b.setPlotTime(times[-1])

When we create the plot, we use the plotPicture method. This causes a QPicture object to be created that can be reused, resized and transformed later without loss of information.


In [4]:
pic1 = b.plotPicture(600, 800)
embed(pic1)

To demonstrate how plots can be combined, we create a smaller plot that shows a different area, and generate another picture from it.


In [5]:
a = plotcommands.Area(name="Europa")
m = plotcommands.Map(map="Gshhs-Auto", backcolour="white", land="on")
m.setOption("land.colour", "flesh")
f.setOption("linewidth", "off")

b.setPlotCommands([a.text(), m.text(), f.text()])
b.setPlotTime(times[-1])

pic2 = b.plotPicture(180, 240)
embed(pic2)

Combining Plots

With two plots stored as pictures, we can use a QPainter object to draw the second one on top of the first. We import some classes we need before creating a new picture to hold the end product, painting both of the existing pictures onto it.


In [6]:
from PyQt4.QtCore import QRect, QSizeF
from PyQt4.QtGui import QColor, QPainter, QPicture, QPrinter

pic3 = QPicture()
pic3.setBoundingRect(QRect(0, 0, 600, 800))
p = QPainter()
p.begin(pic3)
p.drawPicture(0, 0, pic1)
p.fillRect(10, 10, 200, 260, QColor(255, 255, 255))
p.drawPicture(20, 20, pic2)
p.end()

embed(pic3)

Printing the Image

Since the result is stored in a picture, not an image, we can create different products from this in different formats simply by creating a suitable paint device and painting the image onto it. One paint device is QPrinter, which we use to create PDF files.


In [7]:
pr = QPrinter()
pr.setOutputFormat(QPrinter.PdfFormat)
pr.setOutputFileName("/tmp/plot.pdf")
pr.setPaperSize(QSizeF(pic3.width(), pic3.height()), QPrinter.DevicePixel)
pr.setFullPage(True)

With the paint device ready to use, we paint the picture onto it to generate the PDF file.


In [8]:
p = QPainter()
p.begin(pr)
p.drawPicture(0, 0, pic3)
p.end()